/**
 * 图片验证码服务
 * 提供图片验证码的生成、存储和验证功能
 * 
 * 功能特性：
 * - Canvas动态生成验证码图片
 * - 随机干扰线和干扰点
 * - 字符随机旋转和颜色
 * - 5分钟有效期管理
 * - 一次性使用验证码
 * - 自动过期清理
 */

// 验证码存储接口
interface CaptchaCode {
  code: string;         // 验证码文本
  timestamp: number;    // 生成时间戳
  expiresAt: number;    // 过期时间戳
}

// 存储验证码的Map（在实际项目中应该使用session或Redis）
const captchaCodes = new Map<string, CaptchaCode>();

// 验证码有效期（5分钟）
const CAPTCHA_EXPIRY_TIME = 5 * 60 * 1000;

/**
 * 生成随机验证码
 * 从字母和数字中随机选择字符组成验证码
 * 
 * @param length 验证码长度，默认4位
 * @returns 随机验证码字符串
 */
export const generateCaptchaCode = (length: number = 4): string => {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; // 可用字符集
  let result = '';
  for (let i = 0; i < length; i++) {
    result += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  return result;
};

/**
 * 生成图片验证码
 * 使用Canvas API绘制验证码图片，包含干扰元素
 * 
 * @param code 验证码文本
 * @returns 图片验证码的base64数据
 */
export const generateCaptchaImage = (code: string): string => {
  // 创建canvas元素
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  
  if (!ctx) {
    throw new Error('无法创建canvas上下文');
  }

  // 设置canvas尺寸
  canvas.width = 120;
  canvas.height = 40;

  // 设置背景色
  ctx.fillStyle = '#f0f0f0';
  ctx.fillRect(0, 0, canvas.width, canvas.height);

  // 添加干扰线，增加识别难度
  for (let i = 0; i < 3; i++) {
    ctx.strokeStyle = `rgb(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255})`;
    ctx.lineWidth = 1;
    ctx.beginPath();
    ctx.moveTo(Math.random() * canvas.width, Math.random() * canvas.height);
    ctx.lineTo(Math.random() * canvas.width, Math.random() * canvas.height);
    ctx.stroke();
  }

  // 添加干扰点，进一步混淆验证码
  for (let i = 0; i < 30; i++) {
    ctx.fillStyle = `rgb(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255})`;
    ctx.fillRect(Math.random() * canvas.width, Math.random() * canvas.height, 1, 1);
  }

  // 绘制验证码文本
  ctx.font = 'bold 20px Arial';
  ctx.textAlign = 'center';
  ctx.textBaseline = 'middle';
  
  // 为每个字符设置不同的颜色和位置偏移
  for (let i = 0; i < code.length; i++) {
    const x = 30 + i * 20; // 字符水平位置
    const y = 20 + (Math.random() - 0.5) * 10; // 字符垂直位置（随机偏移）
    const rotation = (Math.random() - 0.5) * 0.3; // 字符旋转角度
    
    ctx.save(); // 保存当前绘图状态
    ctx.translate(x, y); // 移动到字符位置
    ctx.rotate(rotation); // 应用旋转
    ctx.fillStyle = `rgb(${Math.random() * 100 + 50}, ${Math.random() * 100 + 50}, ${Math.random() * 100 + 50})`;
    ctx.fillText(code[i], 0, 0); // 绘制字符
    ctx.restore(); // 恢复绘图状态
  }

  // 返回base64图片数据
  return canvas.toDataURL('image/png');
};

/**
 * 创建新的图片验证码
 * 生成验证码文本和图片，并存储到内存中
 * 
 * @param sessionId 会话ID，用于标识验证码
 * @returns 包含验证码图片和会话ID的对象
 */
export const createCaptcha = (sessionId: string): { image: string; sessionId: string } => {
  // 生成验证码
  const code = generateCaptchaCode();
  
  // 生成图片
  const image = generateCaptchaImage(code);
  
  // 存储验证码
  const now = Date.now();
  const captchaCode: CaptchaCode = {
    code,
    timestamp: now,
    expiresAt: now + CAPTCHA_EXPIRY_TIME
  };
  
  captchaCodes.set(sessionId, captchaCode);
  
  // 打印验证码到后台（开发环境使用）
  console.log('=== 图片验证码生成日志 ===');
  console.log('会话ID:', sessionId);
  console.log('验证码:', code);
  console.log('生成时间:', new Date(now).toLocaleString());
  console.log('过期时间:', new Date(captchaCode.expiresAt).toLocaleString());
  console.log('========================');
  
  return { image, sessionId };
};

/**
 * 验证图片验证码
 * 检查验证码是否存在、是否过期、是否匹配
 * 
 * @param sessionId 会话ID
 * @param userInput 用户输入的验证码
 * @returns 验证结果
 */
export const verifyCaptcha = (sessionId: string, userInput: string): boolean => {
  const storedCaptcha = captchaCodes.get(sessionId);
  
  // 检查验证码是否存在
  if (!storedCaptcha) {
    console.log('验证码不存在');
    return false;
  }
  
  // 检查是否过期
  if (Date.now() > storedCaptcha.expiresAt) {
    console.log('验证码已过期');
    captchaCodes.delete(sessionId); // 删除过期验证码
    return false;
  }
  
  // 验证码不区分大小写
  const isValid = storedCaptcha.code.toUpperCase() === userInput.toUpperCase();
  
  console.log('=== 图片验证码验证日志 ===');
  console.log('会话ID:', sessionId);
  console.log('存储的验证码:', storedCaptcha.code);
  console.log('用户输入的验证码:', userInput);
  console.log('验证结果:', isValid ? '成功' : '失败');
  console.log('验证时间:', new Date().toLocaleString());
  console.log('=======================');
  
  // 验证成功后删除验证码，防止重复使用
  if (isValid) {
    captchaCodes.delete(sessionId);
  }
  
  return isValid;
};

/**
 * 获取验证码信息（用于调试）
 * 
 * @param sessionId 会话ID
 * @returns 验证码信息或undefined
 */
export const getCaptchaInfo = (sessionId: string) => {
  return captchaCodes.get(sessionId);
};

/**
 * 清理过期的验证码
 * 定期清理过期的验证码，释放内存
 */
export const cleanupExpiredCaptchas = () => {
  const now = Date.now();
  for (const [sessionId, captcha] of captchaCodes.entries()) {
    if (now > captcha.expiresAt) {
      captchaCodes.delete(sessionId);
      console.log(`清理过期验证码: ${sessionId}`);
    }
  }
};

// 定期清理过期验证码（每分钟执行一次）
setInterval(cleanupExpiredCaptchas, 60 * 1000); 